package com.zy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author LittleDesire
 * @description
 * @date 2022-04-02 周六 10:12
 * @since 17
 */
@Controller
public class IndexController {
    /**
     * 单文件上传
     * @param file 文件
     * @param user 上传用户
     * @param req request
     * @return 上传信息
     */
    @PostMapping("upload") @ResponseBody
    public String upload1(MultipartFile file, String user, HttpServletRequest req) {
        String msg = "上传失败";
        if (file.isEmpty()) {
            msg = "上传失败";
        } else {
            try {
                long fileSize = file.getSize();
                String fileName = file.getOriginalFilename();
                assert fileName != null;
                // lastIndexOf 指定子字符串最后一次出现的索引，如果没有出现，则返回-1 。
                // extension name 后缀名
                String fileExt = fileName.lastIndexOf(".") == -1 ? "" : fileName.toLowerCase().substring(fileName.lastIndexOf("."));
                // %tY%<tm%<td%<tH%<tM%<tS 年与日时分秒
                String filePath = req.getServletContext().getRealPath(String.format("uploads/%tY%<tm%<td",System.currentTimeMillis()));
                File f = new File(filePath);
                if (f.exists()) {
                    f.mkdirs();
                }
                msg = "上传成功："+ fileName;
                file.transferTo(new File(filePath,fileName));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return String.format("%s: %s", user, msg);
    }

    /**
     * 多文件上传
     * @param file 文件
     * @param user 上传用户
     * @param req request
     * @return 上传信息
     */
    @ResponseBody @PostMapping("uploads")
    public String upload2(MultipartFile[] file, String user, HttpServletRequest req) {
        String msg = "上传失败";
        Set<String> set = new HashSet<>();
        if (file.length == 0) {
            msg = "上传失败";
        } else {
            for (MultipartFile mf : file) {
                if (mf.isEmpty()) {
                    try {
                        long fileSize = mf.getSize();
                        String fileName = mf.getOriginalFilename();
                        assert fileName != null;
                        // lastIndexOf 指定子字符串最后一次出现的索引，如果没有出现，则返回-1 。
                        // extension name 后缀名
                        String fileExt = fileName.lastIndexOf(".") == -1 ? "" : fileName.toLowerCase().substring(fileName.lastIndexOf("."));
                        // %tY%<tm%<td%<tH%<tM%<tS 年与日时分秒
                        String filePath = req.getServletContext().getRealPath(String.format("uploads/%tY%<tm%<td", System.currentTimeMillis()));
                        File f = new File(filePath);
                        if (f.exists()) {
                            f.mkdirs();
                        }
                        set.add(fileName);
                        mf.transferTo(new File(filePath, fileName));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            if(!set.isEmpty()) {
                msg = "上传成功：" + set;
            }
        }
        return String.format("%s: %s", user, msg);
    }


    /**
     * 支持单文件多文件多个上传窗口，表单名称不确定
     * @param user 上传用户
     * @param mreq MultipartHttpServletRequest
     * @return 上传信息
     */
    @RequestMapping("uploadss") @ResponseBody
    public String upload3(String user, MultipartHttpServletRequest mreq) {
        AtomicReference<String> msg = new AtomicReference<>("上传失败");
        Set<String> set = new HashSet<>();
        mreq.getMultiFileMap().forEach((fn,mf)->{
            for (Object o : mf.toArray()) {
                MultipartFile fs = (MultipartFile) o;
                if (!fs.isEmpty()) {
                    try {
                        long fileSize = fs.getSize();
                        String fileName = fs.getOriginalFilename();
                        assert fileName != null;
                        // lastIndexOf 指定子字符串最后一次出现的索引，如果没有出现，则返回-1 。
                        // extension name 后缀名
                        String fileExt = fileName.lastIndexOf(".") == -1 ? "" : fileName.toLowerCase().substring(fileName.lastIndexOf("."));
                        // %tY%<tm%<td%<tH%<tM%<tS 年与日时分秒
                        String filePath = mreq.getServletContext().getRealPath(String.format("uploads/%tY%<tm%<td",System.currentTimeMillis()));
                        File f = new File(filePath);
                        if (f.exists()) {
                            f.mkdirs();
                        }
                        fs.transferTo(new File(filePath,fileName));
                        set.add(fileName);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        if (!set.isEmpty()) {
            msg.set("上传成功，"+set);
        }
        return msg.get();
    }



    /**
     * 局部异常处理机制
     * @param exceededException 超出异常
     * @return 超出异常信息
     */
    //@ExceptionHandler
    //@ResponseBody
    public String exception(MaxUploadSizeExceededException exceededException) {
        return exceededException.getMessage();
    }

    /**
     * 上传文件局部异常处理
     * @param e 异常
     * @return 失败异常信息
     */
    @ExceptionHandler
    @ResponseBody
    public String ex(Exception e) {
        String msg = "上传文件失败";
        MaxUploadSizeExceededException mee = (MaxUploadSizeExceededException) e;
        long maxUploadSize = mee.getMaxUploadSize();
        if (Objects.requireNonNull(mee.getMessage()).contains("FileSizeLimitExceededException")) {
            msg += String.format("单个文件不能超过%dMB", maxUploadSize / 1024 / 1024);
        } else if (mee.getMessage().contains("SizeLimitExceededException")) {
            msg += String.format("总大小不能超过%dMB", maxUploadSize / 1024 / 1024);
        } else {
            msg += " 未知异常";
        }
        return msg;
    }
}

